﻿using System;
using System.ServiceModel.Channels;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MockingBird.Common.Infrastructure.DependencyResolution;
using MockingBird.Common.Infrastructure.Logging;
using MockingBird.Simulator.Framework.Configuration;
using MockingBird.Simulator.Framework.Interfaces;
using MockingBird.Simulator.Interceptors.Wcf.Contracts;

namespace MockingBird.Simulator.Interceptors.Wcf.SimulatorService.Tests
{
    [TestClass]
    public class ChessTests
    {
        [TestMethod]
        [HostType("Chess")]
        [TestProperty("ChessDebug", "true")]
        public void ChessTestSimulatorService()
        {
            Message response1 = null;
            Message response2 = null;

            Message request1 = Message.CreateMessage(MessageVersion.Soap11, SimulatorServiceTests.Action1, new DummyMessage("Action1", "IOneWayAsync"));
            request1.Headers.To = new Uri(@"http://localhost/MockingBird/SimulatorService.svc/SelfHost/ITwoWay");
            Message request2 = Message.CreateMessage(MessageVersion.Soap11, SimulatorServiceTests.Action2, new DummyMessage("Action2", "IOneWayAsync"));
            request2.Headers.To = new Uri(@"http://localhost/MockingBird/SimulatorService.svc/SelfHost/ITwoWay");

            ITwoWay simulatorService = new SimulatorService();

            bool executeSynchronous = false;
            if (executeSynchronous)
            {
                response1 = simulatorService.ProcessMessage(request1);
                response2 = simulatorService.ProcessMessage(request2);
            }
            else
            {
                Thread thread1 = new Thread(_ =>
                {
                    response1 = simulatorService.ProcessMessage(request1);
                });
                Thread thread2 = new Thread(_ =>
                {
                    response2 = simulatorService.ProcessMessage(request2);
                });

                thread1.Start();
                thread2.Start();
                thread1.Join();
                thread2.Join();
            }

            DummyMessage dm = response1.GetBody<DummyMessage>();
            Assert.AreEqual<string>("Action1", dm.Action, "Incorrect DummyMessage.Action");

            dm = response2.GetBody<DummyMessage>();
            Assert.AreEqual<string>("Action2", dm.Action, "Incorrect DummyMessage.Action");
        }

        [TestMethod]
        [HostType("Chess")]
        [TestProperty("ChessDebug", "true")]
        public void ChessTestLog4NetLogger()
        {
            Log4NetLogger logger = new Log4NetLogger();
            logger.Log("SomeLogMessage - blahblablabladiesomemoreblahblahblah");
        }

        [TestMethod]
        [HostType("Chess")]
        [TestProperty("ChessDebug", "true")]
        public void ChessTestEntLibLogger()
        {
            EntLibLogger logger = new EntLibLogger();
            logger.Log("SomeLogMessage - blahblablabladiesomemoreblahblahblah");
        }

        [TestMethod]
        [HostType("Chess")]
        [TestProperty("ChessDebug", "true")]
        public void ChessTestUnityContainerSingletonResolveT()
        {
            DependencyResolver.ConfigureDefaultContainer();
            Thread thread1 = new Thread(_ =>
            {
                ILogger l1 = DependencyResolver.DefaultContainer.Resolve<ILogger>();
            });
            Thread thread2 = new Thread(_ =>
            {
                ILogger l2 = DependencyResolver.DefaultContainer.Resolve<ILogger>();
            });

            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();
        }

        [TestMethod]
        [HostType("Chess")]
        [TestProperty("ChessDebug", "true")]
        public void ChessTestUnityContainerPerRequestResolveT()
        {
            DependencyResolver.ConfigureDefaultContainer();
            IConfigurationDataProvider configProvider = DependencyResolver.DefaultContainer.Resolve<IConfigurationDataProvider>();
            ApplicationConfiguration appConfig = new ApplicationConfiguration(configProvider);
            Thread thread1 = new Thread(_ =>
            {
                DependencyResolver.ConfigureDefaultContainer("PerRequest");
                Message request1 = Message.CreateMessage(MessageVersion.Soap11, SimulatorServiceTests.Action1, new DummyMessage("Action1", "IOneWayAsync"));
                request1.Headers.To = new Uri(@"http://localhost/MockingBird/SimulatorService.svc/SelfHost/ITwoWay");

                MockingBird.Simulator.Framework.Interfaces.IExecutionContext execContext = new MockingBird.Simulator.Framework.ExecutionContext(appConfig, request1);
                DependencyResolver.DefaultContainer.RegisterInstance<IExecutionContext>(execContext);
                IHandlerDispenser hd1 = DependencyResolver.DefaultContainer.Resolve<IHandlerDispenser>();
            });
            Thread thread2 = new Thread(_ =>
            {
                DependencyResolver.ConfigureDefaultContainer("PerRequest");
                Message request2 = Message.CreateMessage(MessageVersion.Soap11, SimulatorServiceTests.Action1, new DummyMessage("Action1", "IOneWayAsync"));
                request2.Headers.To = new Uri(@"http://localhost/MockingBird/SimulatorService.svc/SelfHost/ITwoWay");


                MockingBird.Simulator.Framework.Interfaces.IExecutionContext execContext = new MockingBird.Simulator.Framework.ExecutionContext(appConfig, request2);
                DependencyResolver.DefaultContainer.RegisterInstance<IExecutionContext>(execContext);
                IHandlerDispenser hd2 = DependencyResolver.DefaultContainer.Resolve<IHandlerDispenser>();
            });

            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();
        }
    }
}
